package procilege.impl.formatter;

import merisis.sense.SenseMaker;

import org.apache.solr.util.OpenBitSet;

import procilege.compute.ExprFormatTraveller;
import procilege.compute.PlaceTypeMetadata;
import procilege.compute.PlaceType;
import procilege.impl.NameImpl;
import procilege.lang.PredicateExpr;
import procilege.lang.PrivilegeFormTerm;

import com.google.inject.Inject;

@PlaceTypeMetadata(type = PrivilegeFormTerm.class)
public class PrivFormTermFormatter implements PlaceType<ExprFormatTraveller> {

	@Inject
	public SenseMaker nr;

	public void visit(ExprFormatTraveller tr, Object place) {

		PrivilegeFormTerm pft = (PrivilegeFormTerm) place;
		StringBuilder sb = tr.getBuilder();

		formatNameBitSet(tr, sb, pft.fucntions, "(", "*", ")");
		formatNameBitSet(tr, sb, pft.entities, "/(", "&&", ")");

		for (PredicateExpr pe : pft.restrictions) {

			sb.append("[");
			tr.setout(pe);
			sb.append("]");
		}
		formatNameBitSet(tr, sb, pft.bearers, "<", ",", ">");
	}

	private void formatNameBitSet(ExprFormatTraveller tr, StringBuilder sb,
			OpenBitSet bs, String prefix, String postfix, String seperator) {

		if (bs.isEmpty())
			return;

		if (prefix != null)
			sb.append(prefix);

		long i = bs.nextSetBit(0);
		if (i >= 0) {
			tr.setout(new NameImpl(i));

			i = bs.nextSetBit(i + 1);
			while (i >= 0) {

				sb.append(seperator);
				tr.setout(new NameImpl(i));
				i = bs.nextSetBit(i + 1);
			}
		}

		if (postfix != null)
			sb.append(postfix);
	}
}